#include "App_Mac.h"
#include "board.h"
#include "flash-board.h"
#include "rtc-board.h"
#include "sx126x-board.h"
#include "timer.h"
#include "tremo_delay.h"
#include "tremo_gpio.h"
#include "tremo_lpuart.h"
#include "tremo_pwr.h"
#include "tremo_rcc.h"
#include "tremo_regs.h"
#include "tremo_uart.h"
#include "usart-board.h"
#include "utilities.h"
#include <stdio.h>

void BoardInitMcu( void )
{
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_AFEC, true);

    rcc_enable_oscillator(RCC_OSC_XO32K, true);

    rcc_enable_peripheral_clk(RCC_PERIPHERAL_UART0, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_UART1, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_GPIOA, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_GPIOB, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_GPIOC, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_GPIOD, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_PWR, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_RTC, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_SAC, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_LORA, true);
    rcc_enable_peripheral_clk(RCC_PERIPHERAL_SYSCFG, true);

    delay_ms(100);
    pwr_xo32k_lpm_cmd(true);

    Uart0Init(NULL);  // 串口0 LOG串口,DEBUG串口
    SystemParmDataLoad();
    UartInit();
    RtcInit();
    WatchDogConfig();

#if defined(CONFIG_DTU_DOUT)
    SystemDoutConfig();
#endif

#if defined(CONFIG_DTU_AI)
    I2C_init();
#endif

    LOG_PRINTF(LL_DEBUG,"RCC_SYS_CLK = %d\r\n",rcc_get_clk_freq(RCC_SYS_CLK));
    LOG_PRINTF(LL_DEBUG,"RCC_HCLK = %d\r\n",rcc_get_clk_freq(RCC_HCLK));
    LOG_PRINTF(LL_DEBUG,"RCC_PCLK0 = %d\r\n",rcc_get_clk_freq(RCC_PCLK0));
    LOG_PRINTF(LL_DEBUG,"RCC_PCLK1 = %d\r\n",rcc_get_clk_freq(RCC_PCLK1));
}

void BoardDeInitMcu( void )
{

}

uint32_t BoardGetRandomSeed( void )
{
    return 0;
}


#if defined(CONFIG_DTU_DOUT)
void SystemDoutConfig(void)
{
    rcc_enable_peripheral_clk(SYSTEM_DOUT1_RCC, true);
    gpio_init(SYSTEM_DOUT1_GPIO, SYSTEM_DOUT1_PIN, GPIO_MODE_OUTPUT_PP_LOW);
    gpio_set_iomux(SYSTEM_DOUT1_GPIO, SYSTEM_DOUT1_PIN, 0);

    rcc_enable_peripheral_clk(SYSTEM_DOUT2_RCC, true);
    gpio_init(SYSTEM_DOUT2_GPIO, SYSTEM_DOUT2_PIN, GPIO_MODE_OUTPUT_PP_LOW);
    gpio_set_iomux(SYSTEM_DOUT2_GPIO, SYSTEM_DOUT2_PIN, 0);
}


void SystemDoutModeSet(uint8_t attrId,uint8_t state)
{
    switch(attrId)
    {
        case 1:
        {
            if(state)
            {
                gpio_write(SYSTEM_DOUT1_GPIO,SYSTEM_DOUT1_PIN, GPIO_LEVEL_HIGH);
            }
            else
            {
                gpio_write(SYSTEM_DOUT1_GPIO,SYSTEM_DOUT1_PIN, GPIO_LEVEL_LOW);
            }
            break;
        }

        case 2:
        {
            if(state)
            {
                gpio_write(SYSTEM_DOUT2_GPIO,SYSTEM_DOUT2_PIN, GPIO_LEVEL_HIGH);
            }
            else
            {
                gpio_write(SYSTEM_DOUT2_GPIO,SYSTEM_DOUT2_PIN, GPIO_LEVEL_LOW);
            }
            break;
        }
    }
}

#endif




#if defined(CONFIG_DTU_DIN)
void SystemDinConfig(void)
{
    rcc_enable_peripheral_clk(SYSTEM_DIN1_RCC, true);
    gpio_init(SYSTEM_DIN1_GPIO, SYSTEM_DIN1_PIN, GPIO_MODE_INPUT_PULL_DOWN);
    gpio_set_iomux(SYSTEM_DIN1_GPIO, SYSTEM_DIN1_PIN, 0);

    rcc_enable_peripheral_clk(SYSTEM_DIN2_RCC, true);
    gpio_init(SYSTEM_DIN2_GPIO, SYSTEM_DIN2_PIN, GPIO_MODE_INPUT_PULL_DOWN);
    gpio_set_iomux(SYSTEM_DIN2_GPIO, SYSTEM_DIN2_PIN, 0);

    rcc_enable_peripheral_clk(SYSTEM_DIN3_RCC, true);
    gpio_init(SYSTEM_DIN3_GPIO, SYSTEM_DIN3_PIN, GPIO_MODE_INPUT_PULL_DOWN);
    gpio_set_iomux(SYSTEM_DIN3_GPIO, SYSTEM_DIN3_PIN, 0);

    rcc_enable_peripheral_clk(SYSTEM_DIN4_RCC, true);
    gpio_init(SYSTEM_DIN4_GPIO, SYSTEM_DIN4_PIN, GPIO_MODE_INPUT_PULL_DOWN);
    gpio_set_iomux(SYSTEM_DIN4_GPIO, SYSTEM_DIN4_PIN, 0);
}


uint8_t SystemDinModeGet(uint8_t attrId)
{
    uint8_t state = 0;
    switch(attrId)
    {
        case 1:
        {
            state = gpio_read(SYSTEM_DIN1_GPIO, SYSTEM_DIN1_PIN);
            break;
        }

        case 2:
        {
            state = gpio_read(SYSTEM_DIN2_GPIO, SYSTEM_DIN2_PIN);
            break;
        }
        case 3:
        {
            state = gpio_read(SYSTEM_DIN3_GPIO, SYSTEM_DIN3_PIN);
            break;
        }

        case 4:
        {
            state = gpio_read(SYSTEM_DIN4_GPIO, SYSTEM_DIN4_PIN);
            break;
        }
    }
}

#endif




void WatchDogConfig(void)
{
    rcc_enable_peripheral_clk(SYSTEM_WATCHDOG_RCC, true);
    gpio_init(SYSTEM_WATCHDOG_GPIO, SYSTEM_WATCHDOG_PIN, GPIO_MODE_OUTPUT_PP_LOW);
    gpio_set_iomux(SYSTEM_WATCHDOG_GPIO, SYSTEM_WATCHDOG_PIN, 0); // GPIO02为GPIO功能
    WatchDogToggle();
}

void WatchDogToggle(void)
{
    gpio_toggle(SYSTEM_WATCHDOG_GPIO,SYSTEM_WATCHDOG_PIN);
}



volatile uint8_t SystemLoopThroughMain = 0;
void SystemEnterSleep(void)
{
    LOG_PRINTF(LL_DEBUG,"SystemEnterSleep,SystemLoopThroughMain=%d\r\n",SystemLoopThroughMain);
    if( SystemLoopThroughMain < 5 )
    {
        SystemLoopThroughMain++;
    }
    else
    {
        SystemLoopThroughMain = 0;

        if (Radio.GetStatus() != RF_IDLE) {
            return;
        }

        BoardDeInitMcu( );
        pwr_deepsleep_wfi(PWR_LP_MODE_STOP3);
        DeviceState = DEVICE_STATE_IDLE;
    }
}
